import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ServerMessageHandleThread extends Thread {
    private Socket socket;
    public ServerMessageHandleThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        loadUsersDefault();

        try {
            BufferedReader br = wrapByInputStream(socket.getInputStream());
            String line = "";
            String allLine = "";
            while((line = br.readLine()) != null){
                allLine += line;
            }
            handleLine(allLine,socket);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }





    private List<String> users = new ArrayList<>();
    private Map<String , Socket> userSocketMap = new HashMap<>();
    public void loadUsersDefault() {
        String defaultName = "C:\\Users\\fushiyong\\Documents\\WeChat Files\\wxid_4mf7hg2zjqyq12\\FileStorage\\File\\2020-11\\Chat\\Chat\\src\\User.txt";
        File file = new File(defaultName);
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
            String line = null;
            while(true){
                try {
                    if (!((line = br.readLine()) != null))
                        break;
                } catch (IOException e) {
                    e.printStackTrace();
                }

                users.add(line);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 协议以逗号分割 ，切分为数组，  数字第一个为命令 ， 数字第二三个是对应命令的内容
     * @param line
     * @return
     */
    private void handleLine(String line,Socket socket) {
        //exit 退出 login 登录
        String spliter = "--,--";
        String [] uuidCommandContent = line.split(spliter);
        String username = uuidCommandContent[0];
        String command = uuidCommandContent[1];


        String resp = null;

        //登录    1001 --,--  login
        if("login".equals(command)){
            if(users.contains(username)){
                resp ="登陆成功,"+username;
                userSocketMap.put(username , socket);
                appendToTextArea(username , "" , "用户登录");
            }else{
                resp ="登陆失败";
            }

            writeMessage(resp , socket);

            return;
        }

        //已登录


        if("exit".equals(command)){
            closeSocketQuiet(socket);
            userSocketMap.remove(username);
        }

        // uuid --,-- chat --,-- fushiyong , fushiyong2 , message
        else if("chat".equals(command)){
            String  options = uuidCommandContent[2]; //多个参数以，分割
            String[] optionParams = options.split(",");
            String from = optionParams[0];
            String to = optionParams[1];
            String message = optionParams[2];
            Socket toSocket = findSocketByUsername(to);
            writeMessage(message , toSocket);
            appendToTextArea(from , to , message);
        }
    }

    private void appendToTextArea(String from, String to, String message) {
        String content = ServerJFrame.jTextArea1.getText();
        String appendLine = "from "+ from +":" + message;
        String replaced = content + "\n" + appendLine;
        ServerJFrame.jTextArea1.setText(replaced);
    }

    private Socket findSocketByUsername(String usernameParam){
        for(Map.Entry<String,Socket> userSocketEntry : this.userSocketMap.entrySet()){
            String username = userSocketEntry.getKey();
            Socket socket = userSocketEntry.getValue();
            if(username.equals(usernameParam)){
                return socket;
            }
        }
        return null;
    }
    private void writeMessage(String message, Socket socket) {
        try {
            PrintWriter pw = wrapByOutputStream(socket.getOutputStream());
            pw.write(message);
            pw.flush();
            socket.shutdownOutput();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void closeSocketQuiet(Socket socket) {
        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public BufferedReader wrapByInputStream(InputStream in){
        return new BufferedReader(new InputStreamReader(in));
    }

    public PrintWriter wrapByOutputStream(OutputStream out){
        return new PrintWriter(new OutputStreamWriter(out));
    }
    // End of variables declaration
}
